﻿using System.Linq;
using easyccms.BusinessLayer;
using easyccms.BusinessLayer.Entities;

namespace easyccms.Nhibernate.Repositories
{
    /// <summary>
    /// A generic repository providing standard functionality to repositories that extend it.
    /// </summary>
    /// <typeparam name="T">The entity managed by the repository.</typeparam>
    public abstract class Repository<T> where T : Entity
    {
        /// <summary>
        /// Protected unit of work that is responsible for session that is responsibility for saving loading data.
        /// </summary>
        private IUnitOfWork UnitOfWork;

        /// <summary>
        /// Initializes a new instance of the <see cref="Repository&lt;T&gt;"/> class.
        /// This works as base class for repository.
        /// </summary>
        /// <param name="unitOfWork">The unit of work.</param>
        internal Repository(IUnitOfWork unitOfWork)
        {
            this.UnitOfWork = unitOfWork;
        }
       
        /// <summary>
        /// Gets all data from database for entity.
        /// </summary>
        public IQueryable<T> All
        {
            get { return this.UnitOfWork.GetList<T>(); }
        }

        /// <summary>
        /// Loads the specified entity from id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns>Returns loaded entity from id.</returns>
        public T Load(int id)
        {
            T t;
            t = this.UnitOfWork.Load<T>(id);
            return t;
        }

        /// <summary>
        /// Saves the specified entity into database.
        /// </summary>
        /// <param name="t">Save entity to database.</param>
        public virtual void Save(T t)
        {
            this.UnitOfWork.Save(t);
        }

        /// <summary>
        /// Deletes the specified entity t.
        /// </summary>
        /// <param name="t">The entity t to be deleted.</param>
        public virtual void Delete(T t)
        {
            this.UnitOfWork.Delete(t);
        }

        public IUnitOfWork GetUnitOfWork()
        {
            return this.UnitOfWork;
        }
    }
}